import { Component } from '../core/Component';
import { GameObject } from '../core/GameObject';
import { TextAlign, TextBaseline, TextStyle } from './types';

export interface TextOptions extends TextStyle {
    /**
     * 文本内容
     */
    text: string;
    
    /**
     * 是否可见
     */
    visible?: boolean;
    
    /**
     * 透明度
     */
    alpha?: number;
    
    /**
     * 混合模式
     */
    compositeOperation?: GlobalCompositeOperation;
    
    /**
     * 是否自动换行
     */
    wordWrap?: boolean;
    
    /**
     * 自动换行宽度
     */
    wordWrapWidth?: number;
}

export class Text extends Component {
    private text: string;
    private style: Required<TextStyle>;
    private visible: boolean;
    private alpha: number;
    private compositeOperation: GlobalCompositeOperation;
    private wordWrap: boolean;
    private wordWrapWidth: number;
    private lines: string[];
    
    constructor(gameObject: GameObject, options: TextOptions) {
        super(gameObject);
        
        this.text = options.text;
        this.style = {
            font: options.font ?? '16px Arial',
            color: options.color ?? '#000000',
            align: options.align ?? TextAlign.LEFT,
            baseline: options.baseline ?? TextBaseline.TOP,
            lineHeight: options.lineHeight ?? 1.2,
            letterSpacing: options.letterSpacing ?? 0,
            wordSpacing: options.wordSpacing ?? 0,
            maxWidth: options.maxWidth ?? 0
        };
        this.visible = options.visible ?? true;
        this.alpha = options.alpha ?? 1;
        this.compositeOperation = options.compositeOperation ?? 'source-over';
        this.wordWrap = options.wordWrap ?? false;
        this.wordWrapWidth = options.wordWrapWidth ?? 0;
        this.lines = [];
        
        // 初始化文本行
        this.updateLines();
    }
    
    /**
     * 设置文本内容
     */
    public setText(text: string): void {
        if (this.text !== text) {
            this.text = text;
            this.updateLines();
        }
    }
    
    /**
     * 获取文本内容
     */
    public getText(): string {
        return this.text;
    }
    
    /**
     * 设置文本样式
     */
    public setStyle(style: Partial<TextStyle>): void {
        this.style = { ...this.style, ...style };
        this.updateLines();
    }
    
    /**
     * 获取文本样式
     */
    public getStyle(): Required<TextStyle> {
        return { ...this.style };
    }
    
    /**
     * 设置可见性
     */
    public setVisible(visible: boolean): void {
        this.visible = visible;
    }
    
    /**
     * 获取可见性
     */
    public getVisible(): boolean {
        return this.visible;
    }
    
    /**
     * 设置透明度
     */
    public setAlpha(alpha: number): void {
        this.alpha = Math.max(0, Math.min(1, alpha));
    }
    
    /**
     * 获取透明度
     */
    public getAlpha(): number {
        return this.alpha;
    }
    
    /**
     * 设置混合模式
     */
    public setCompositeOperation(operation: GlobalCompositeOperation): void {
        this.compositeOperation = operation;
    }
    
    /**
     * 获取混合模式
     */
    public getCompositeOperation(): GlobalCompositeOperation {
        return this.compositeOperation;
    }
    
    /**
     * 设置自动换行
     */
    public setWordWrap(enabled: boolean, width?: number): void {
        this.wordWrap = enabled;
        if (width !== undefined) {
            this.wordWrapWidth = width;
        }
        this.updateLines();
    }
    
    /**
     * 获取自动换行状态
     */
    public getWordWrap(): { enabled: boolean; width: number } {
        return {
            enabled: this.wordWrap,
            width: this.wordWrapWidth
        };
    }
    
    /**
     * 更新文本行
     */
    private updateLines(): void {
        if (!this.wordWrap || !this.wordWrapWidth) {
            this.lines = [this.text];
            return;
        }
        
        const words = this.text.split(/\s+/);
        const lines: string[] = [];
        let currentLine = '';
        
        // 创建临时canvas以测量文本宽度
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d')!;
        ctx.font = this.style.font;
        
        for (const word of words) {
            const testLine = currentLine ? `${currentLine} ${word}` : word;
            const metrics = ctx.measureText(testLine);
            
            if (metrics.width > this.wordWrapWidth) {
                if (currentLine) {
                    lines.push(currentLine);
                    currentLine = word;
                } else {
                    // 如果单个词就超过宽度，强制换行
                    lines.push(word);
                    currentLine = '';
                }
            } else {
                currentLine = testLine;
            }
        }
        
        if (currentLine) {
            lines.push(currentLine);
        }
        
        this.lines = lines;
    }
    
    /**
     * 测量文本尺寸
     */
    public measureText(): { width: number; height: number } {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d')!;
        
        // 设置文本样式
        ctx.font = this.style.font;
        ctx.textAlign = this.style.align;
        ctx.textBaseline = this.style.baseline;
        
        // 计算文本尺寸
        let maxWidth = 0;
        let totalHeight = 0;
        
        for (const line of this.lines) {
            const metrics = ctx.measureText(line);
            maxWidth = Math.max(maxWidth, metrics.width);
            const fontSize = parseInt(this.style.font) || 16;
            totalHeight += fontSize * this.style.lineHeight;
        }
        
        return {
            width: maxWidth,
            height: totalHeight
        };
    }
    
    /**
     * 渲染组件
     */
    public render(ctx: CanvasRenderingContext2D): void {
        if (!this.visible) {
            return;
        }
        
        // 保存当前状态
        ctx.save();
        
        // 设置混合模式和透明度
        ctx.globalCompositeOperation = this.compositeOperation;
        ctx.globalAlpha = this.alpha;
        
        // 设置文本样式
        ctx.font = this.style.font;
        ctx.fillStyle = this.style.color;
        ctx.textAlign = this.style.align;
        ctx.textBaseline = this.style.baseline;
        
        // 获取游戏对象的位置和缩放
        const transform = this.gameObject.transform;
        const position = transform.position;
        const scale = transform.scale;
        const rotation = transform.rotation;
        
        // 设置变换
        ctx.translate(position.x, position.y);
        ctx.rotate(rotation);
        ctx.scale(scale.x, scale.y);
        
        // 计算行高
        const fontSize = parseInt(this.style.font);
        const lineHeight = fontSize * this.style.lineHeight;
        
        // 绘制文本行
        let y = 0;
        for (const line of this.lines) {
            // 应用字母间距
            if (this.style.letterSpacing !== 0) {
                const chars = line.split('');
                let x = 0;
                
                for (const char of chars) {
                    ctx.fillText(char, x, y);
                    x += ctx.measureText(char).width + this.style.letterSpacing;
                }
            } else {
                ctx.fillText(line, 0, y);
            }
            
            y += lineHeight;
        }
        
        // 恢复状态
        ctx.restore();
    }
    
    /**
     * 销毁组件
     */
    public destroy(): void {
        this.lines = [];
        super.destroy();
    }
} 